Time-based Blind SQL Injection
SQLクエリの結果がこちら側に出力されないときに有効
usernameとpasswordを使ってログイン処理のときSQL Injectionできる
データベースはMySQLとする
ただし、今回はログインするだけでなくadminのpassを知りたい
こちらからわかるのはログイン可否だけだから、直接adminのpassを知ることはできない
usernameにhoge、passwordに以下のような入力を入れてみる
' OR IF(SUBSTR((SELECT pass FROM user WHERE name='admin'), 1, 1)='a', sleep(5), 1) --
クエリは以下のようになる
SELECT * FROM user WHERE user='hoge' AND pass='' OR IF(SUBSTR((SELECT pass FROM user WHERE name='admin'), 1, 1), sleep(5), 1)'
IFは常に評価される
サブクエリを使ってadminのpassを取得し、SUBSTRで一文字目を取得する
その文字がaかどうかを判定し、真のときsleep(5)を実行する
まとめると、adminのpassの一文字目がaのときに5秒間処理が停止する
正常なときの応答時間と比べると、adminのpassがaかどうかわかる
これをaだけでなく全ての文字について総当たりすれば、一文字目がわかる
2文字目以降も同様に求めれば、adminのpassがわかる!
文字を総当たりするのではなく、ASCIIなどを使って文字コードで二分探索すると高速になる
Time-basedに情報を特定する手法は様々なところで応用できる
IFやSLEEPは他のRDBMSでは使えなかったりするので、チートシートを参考にすると楽